__all__=["HandleBox"]

from OpenGL.GL import *
from OpenGL.GLU import *
from graphicobject import *

class HandleBox(GraphicObject):
    """This object is to be used as a manipulator for other graphicobjects. 
    The idea is that each handlebox object is attached to some other object.
    Altering the transformation of this object also alters the attached object.
    """
    
    def __init__(self, attached):
        """Constructor.
        @param attached: a slave object which will be transformed whenever
        this box is transformed. 
        """
        GraphicObject.__init__(self,None)
        self.attached = attached
    
    def drawAnchors (self):
        """Draw small square anchors at each vertex of the box."""
        #Must first figure out a reasonable size for the squares
        modelview = glGetDoublev(GL_MODELVIEW_MATRIX)
        projection = glGetDoublev(GL_PROJECTION_MATRIX)
        viewport = glGetIntegerv(GL_VIEWPORT)
        c = gluProject (0,0,0,modelview,projection,viewport)
        x = gluProject (1,0,0,modelview,projection,viewport)
        y = gluProject (0,1,0,modelview,projection,viewport)
        z = gluProject (0,0,1,modelview,projection,viewport)
        d = 20.0 /max(abs(x[0]-c[0]),abs(y[0]-c[0]),abs(z[0]-c[0]), \
                     abs(x[1]-c[1]),abs(y[1]-c[1]),abs(z[1]-c[1]))
  
        # get the box vertices
        vtx = self.attached.box.vertices()
        edgeincr = ((d,d,d), (-d,d,d), (d,-d,d), (-d,-d,d), 
                    (d,d,-d), (-d,d,-d), (d,-d,-d), (-d,-d,-d))
        i = 0
        for v,e in zip(vtx,edgeincr):
            dx,dy,dz=e
            vx,vy,vz=v
            glLoadName(i)
            i += 1
            glBegin(GL_TRIANGLE_FAN)
            glVertex3fv (v)
            glVertex3f (vx+dx,vy,vz)
            glVertex3f (vx+dx,vy+dy,vz)
            glVertex3f (vx,vy+dy,vz)
            glVertex3f (vx,vy+dy,vz+dz)
            glVertex3f (vx,vy,vz+dz)
            glVertex3f (vx+dx,vy,vz+dz)
            glVertex3f (vx+dx,vy,vz)    
            glEnd()
        
    def draw(self):
        """Draws the box."""
        glPushAttrib(GL_LIGHTING_BIT)
        glDisable(GL_LIGHTING)
        glMultMatrixd (self.attached.transformation)
        self.attached.box.draw()
        glPushName(0)
        self.drawAnchors()
        glPopName()
        glPopAttrib()
            


